Android无障碍简单开发 | 您所在的位置:网站首页 › 滑动输入 安卓怎么设置的 › Android无障碍简单开发 |
以下文章转载自:https://blog.csdn.net/Dullyoung/article/details/106090220 (Android无障碍服务开发QQ群:752296312) 似乎除了input type=password的edit text 其他所有的UI都可以进行操作。直接开始。 1 首先配置环境。 创建一个service 清单中代码如下,就算用AS直接创建,也需要配置一些权限等东西。 label 无障碍的名字,显示在系统辅助功能->无障碍界面的标题。权限不能掉,而且必须放在这。不能和其他权限一样放在上面。resource是无障碍服务的相关配置。xml文件如下: //我直接写的注释 复制粘贴记得删除 不然会报错 //要检测的窗口或应用的包名 各个属性的内容和含义看这个无障碍参数详情 然后新建一个MyAccessibilityService继承AccessibilityService 重写onAccessibilityEvent()和onInterrupt() 在onAccessibilityEvent()中操作,在检测到目标包名在前台运行的时候会回调这个方法,然后我们在这获取根视图。 try { //拿到根节点 AccessibilityNodeInfo rootInfo = getRootInActiveWindow(); if (rootInfo == null) { return; } //开始找目标节点,这里拎出来细讲,直接往下看正文 if (rootInfo.getChildCount() != 0) { if (rootInfo == null || TextUtils.isEmpty(rootInfo.getClassName())) { return; } //开始去找 findByID(rootInfo, "com.tencent.mobileqq:id/chat_item_content_layout"); } } catch (Exception e) { } findByID方法如下: private void findByID(AccessibilityNodeInfo rootInfo, String text) { if (rootInfo.getChildCount() > 0) { for (int i = 0; i < rootInfo.getChildCount(); i++) { AccessibilityNodeInfo child = rootInfo.getChild(i); try { if (child.findAccessibilityNodeInfosByViewId(text).size() > 0) { for (AccessibilityNodeInfo info : child.findAccessibilityNodeInfosByViewId(text)) { performClick(getClickable(info)); //模仿全局手势 // performGlobalAction(GLOBAL_ACTION_NOTIFICATIONS); } } } catch (NullPointerException e) { } findByID(child, text);//递归一直找一层层的全部遍历 } } } id通过DDMS看 有些控件处在listview或recyclerview下,就导致id重复,所以再用text匹配。 performClick(getClickable(info));这里的一个方法。 //有些节点不可点击 点击交给父级甚至父级的父级...来做的。 private AccessibilityNodeInfo getClickable(AccessibilityNodeInfo info) { Log.i(TAG, info.getClassName() + ": " + info.isClickable()); if (info.isClickable()) { return info;//如果可以点击就返回 } else {//不可点击就检查父级 一直递归 return getClickable(info.getParent()); } } 此外通过文本内容来找到视图 private AccessibilityNodeInfo findByText(AccessibilityNodeInfo rootInfo, String text) { if (rootInfo.getChildCount() > 0) { for (int i = 0; i < rootInfo.getChildCount(); i++) { AccessibilityNodeInfo child = rootInfo.getChild(i); try { if (child.findAccessibilityNodeInfosByText(text).size() > 0) { for (AccessibilityNodeInfo info : child.findAccessibilityNodeInfosByText(text)) { performClick(getClickable(info)); return null; } } } catch (NullPointerException e) { } findByText(child, text); } } return null; } 找到了视图之后,就可以做各种动作,如输入框输入: private void changeInput(AccessibilityNodeInfo info,String text) { //改变editText的内容 Bundle arguments = new Bundle(); arguments.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, text); info.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, arguments); } 再如模拟手势: private void MyGesture(){//仿滑动 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { Path path = new Path(); path.moveTo(1000, 1000);//滑动起点 path.lineTo(2000, 1000);//滑动终点 GestureDescription.Builder builder = new GestureDescription.Builder(); GestureDescription description = builder.addStroke(new GestureDescription.StrokeDescription(path, 100L, 100L)).build(); //100L 第一个是开始的时间,第二个是持续时间 dispatchGesture(description, new MyCallBack(), null); } } 模拟手势监听的回调: //模拟手势的监听 @RequiresApi(api = Build.VERSION_CODES.N) private class MyCallBack extends GestureResultCallback { public MyCallBack() { super(); } @Override public void onCompleted(GestureDescription gestureDescription) { super.onCompleted(gestureDescription); } @Override public void onCancelled(GestureDescription gestureDescription) { super.onCancelled(gestureDescription); } } 只是用无障碍可以实现点击 向上滑动 向下滑动,输入等等,左右滑动需要通过模拟手势来达到,但是模拟手势需要7.0+。 因为系统原因,无障碍服务每次运行完都得重新开启 快捷跳转 到无障碍设置界面 Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS); startActivity(intent); 开启无障碍服务之后,再启动无障碍服务的Service startService(new Intent(this, MyAccessibilityService.class)); 无障碍服务基本可以捕捉所有界面并点击,包括6.0+弹窗授权。 |
CopyRight 2018-2019 实验室设备网 版权所有 |